# [Spring Data JPA] ๋”ํ‹ฐ ์ฒดํ‚น (Dirty Checking)



ํŠธ๋žœ์žญ์…˜ ์•ˆ์—์„œ Entity์˜ ๋ณ€๊ฒฝ์ด ์ผ์–ด๋‚ฌ์„ ๋•Œ
๋ณ€๊ฒฝํ•œ ๋‚ด์šฉ์„ ์ž๋™์œผ๋กœ DB์— ๋ฐ˜์˜ํ•˜๋Š” ๊ฒƒ

ORM ๊ตฌํ˜„์ฒด ๊ฐœ๋ฐœ ์‹œ ๋”ํ‹ฐ ์ฒดํ‚น์ด๋ผ๋Š” ๋ง์„ ์ž์ฃผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

๋”ํ‹ฐ ์ฒดํ‚น์ด ์–ด๋–ค ๊ฒƒ์„ ๋œปํ•˜๋Š” ์ง€ ๊ฐ„๋‹จํžˆ ์‚ดํŽด๋ณด์ž.


JPA๋กœ ๊ฐœ๋ฐœํ•˜๋Š” ๊ฒฝ์šฐ ๊ตฌํ˜„ํ•œ ํ•œ ๊ฐ€์ง€ ๊ธฐ๋Šฅ์„ ์˜ˆ๋กœ ๋“ค์–ด๋ณด์ž

# ex) ์ฃผ๋ฌธ ์ทจ์†Œ ๊ธฐ๋Šฅ
@Transactional  
public void cancelOrder(Long orderId) {  
    //์ฃผ๋ฌธ ์—”ํ‹ฐํ‹ฐ ์กฐํšŒ  
    Order order = orderRepository.findOne(orderId);  

    //์ฃผ๋ฌธ ์ทจ์†Œ  
    order.cancel();  
}

orderId๋ฅผ ํ†ตํ•ด ์ฃผ๋ฌธ์„ ์ทจ์†Œํ•˜๋Š” ๋ฉ”์†Œ๋“œ๋‹ค. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ฐ˜์˜ํ•˜๊ธฐ ์œ„ํ•ด์„ , update์™€ ๊ฐ™์€ ์ฟผ๋ฆฌ๊ฐ€ ์žˆ์–ด์•ผํ•  ๊ฒƒ ๊ฐ™์€๋ฐ ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค.

ํ•˜์ง€๋งŒ, ์‹ค์ œ๋กœ ์ด ๋ฉ”์†Œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— update๊ฐ€ ์ž˜ ์ด๋ฃจ์–ด์ง„๋‹ค.

  • ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘
  • orderId๋กœ ์ฃผ๋ฌธ Entity ์กฐํšŒ
  • ํ•ด๋‹น Entity ์ฃผ๋ฌธ ์ทจ์†Œ ์ƒํƒœ๋กœ Update
  • ํŠธ๋žœ์žญ์…˜ ์ปค๋ฐ‹

์ด๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” ๊ฒƒ์ด ๋ฐ”๋กœ '๋”ํ‹ฐ ์ฒดํ‚น(Dirty Checking)'์ด๋ผ๊ณ  ๋ณด๋ฉด ๋œ๋‹ค.


๊ทธ๋ƒฅ ๋”ํ‹ฐ ์ฒดํ‚น์˜ ๋‹จ์–ด๋งŒ ๊ฐ„๋‹จํžˆ ํ•ด์„ํ•˜๋ฉด ๋ณ€๊ฒฝ ๊ฐ์ง€๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ข€ ๋” ์ž์„ธํžˆ ๋งํ•˜๋ฉด, Entity์—์„œ ๋ณ€๊ฒฝ์ด ์ผ์–ด๋‚œ ๊ฑธ ๊ฐ์ง€ํ•œ ๋’ค, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ฐ˜์˜์‹œ์ผœ์ค€๋‹ค๋Š” ์˜๋ฏธ๋‹ค. (๋ณ€๊ฒฝ์€ ์ตœ์ดˆ ์กฐํšŒ ์ƒํƒœ๊ฐ€ ๊ธฐ์ค€์ด๋‹ค)

Dirty : ์ƒํƒœ์˜ ๋ณ€ํ™”๊ฐ€ ์ƒ๊น€

Checking : ๊ฒ€์‚ฌ

JPA์—์„œ๋Š” ํŠธ๋žœ์žญ์…˜์ด ๋๋‚˜๋Š” ์‹œ์ ์— ๋ณ€ํ™”๊ฐ€ ์žˆ๋˜ ๋ชจ๋“  ์—”ํ‹ฐํ‹ฐ์˜ ๊ฐ์ฒด๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ ์•Œ์•„์„œ ๋ฐ˜์˜์„ ์‹œ์ผœ์ค€๋‹ค. ์ฆ‰, ํŠธ๋žœ์žญ์…˜์˜ ๋งˆ์ง€๋ง‰ ์‹œ์ ์—์„œ ๋‹ค๋ฅธ ์ ์„ ๋ฐœ๊ฒฌํ–ˆ์„ ๋•Œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ update ์ฟผ๋ฆฌ๋ฅผ ๋‚ ๋ ค์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.

  • JPA์—์„œ Entity๋ฅผ ์กฐํšŒ
  • ์กฐํšŒ๋œ ์ƒํƒœ์˜ Entity์— ๋Œ€ํ•œ ์Šค๋ƒ…์ƒท ์ƒ์„ฑ
  • ํŠธ๋žœ์žญ์…˜ ์ปค๋ฐ‹ ํ›„ ํ•ด๋‹น ์Šค๋ƒ…์ƒท๊ณผ ํ˜„์žฌ Entity ์ƒํƒœ์˜ ๋‹ค๋ฅธ ์ ์„ ์ฒดํฌ
  • ๋‹ค๋ฅธ ์ ๋“ค์„ update ์ฟผ๋ฆฌ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ „๋‹ฌ

์ด๋•Œ ๋”ํ‹ฐ ์ฒดํ‚น์„ ๊ฒ€์‚ฌํ•˜๋Š” ๋Œ€์ƒ์€ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ๊ด€๋ฆฌํ•˜๋Š” Entity๋กœ๋งŒ ๋Œ€์ƒ์œผ๋กœ ํ•œ๋‹ค.

์ค€์˜์†, ๋น„์˜์† Entity๋Š” ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ง€๋ผ๋„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ฐ˜์˜์‹œํ‚ค์ง€ ์•Š๋Š”๋‹ค.


๊ธฐ๋ณธ์ ์œผ๋กœ ๋”ํ‹ฐ ์ฒดํ‚น์„ ์‹คํ–‰ํ•˜๋ฉด, SQL์—์„œ๋Š” ๋ณ€๊ฒฝ๋œ ์—”ํ‹ฐํ‹ฐ์˜ ๋ชจ๋“  ๋‚ด์šฉ์„ update ์ฟผ๋ฆฌ๋กœ ๋งŒ๋“ค์–ด ์ „๋‹ฌํ•˜๋Š”๋ฐ, ์ด๋•Œ ํ•„๋“œ๊ฐ€ ๋งŽ์•„์ง€๋ฉด ์ „์ฒด ํ•„๋“œ๋ฅผ updateํ•˜๋Š”๊ฒŒ ๋น„ํšจ์œจ์ ์ผ ์ˆ˜๋„ ์žˆ๋‹ค.

์ด๋•Œ๋Š” @DynamicUpdate๋ฅผ ํ•ด๋‹น Entity์— ์„ ์–ธํ•˜์—ฌ ๋ณ€๊ฒฝ ํ•„๋“œ๋งŒ ๋ฐ˜์˜์‹œํ‚ค๋„๋ก ๋งŒ๋“ค์–ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

@Getter
@NoArgsConstructor
@Entity
@DynamicUpdate
public class Order {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String product;


# [์ฐธ๊ณ  ์ž๋ฃŒ]

์ตœ์ข… ์ˆ˜์ • : 12/17/2022, 7:23:59 AM